package com.atguigu.gmall.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.common.util.HttpClientUtil;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.task.config.MqConst;
import com.atguigu.gmall.task.service.RabbitService;
import com.atguigu.gmall.order.mapper.CartInfoMapper;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: 李旭
 * @create: 2021-07-23 15:45
 **/
@Service
public class OrderInfoServiceImpl implements OrderInfoService {


    @Value("${ware.url}")
    private String wareUrl;
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CartInfoMapper cartInfoMapper;

    //查询是否有货boolean  true 有货  false 无货
    @Override
    public boolean isHave(OrderDetail orderDetail) {
        return "1".equals(HttpClientUtil.doGet(wareUrl + "/hasStock?skuId=" +
                orderDetail.getSkuId() + "&num=" + orderDetail.getSkuNum()));
    }

    //提交订单
    @Override
    @Transactional
    public Long saveOrder(OrderInfo orderInfo) {
        //1：保存订单主表
        //订单状态
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());//UNPAID
        //orderInfo.setOrderStatus(OrderStatus.UNPAID.getComment());//未支付
        //订单交易编号
        String outTradeNo = "atguigu" + System.currentTimeMillis() + new Random().nextInt(1000);
        orderInfo.setOutTradeNo(outTradeNo);
        //订单描述
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        StringBuilder sb = new StringBuilder();
        for (OrderDetail orderDetail : orderDetailList) {
            sb.append(orderDetail.getSkuName() + " ");
            BigDecimal price = productFeignClient.getPrice(orderDetail.getSkuId());
            orderDetail.setOrderPrice(price);

        }
        if (sb.length() > 100) {
            orderInfo.setTradeBody(sb.substring(0, 100));
        } else {
            orderInfo.setTradeBody(sb.toString());
        }
        Calendar calendar = Calendar.getInstance();
        //创建时间
        orderInfo.setCreateTime(calendar.getTime());
        //失效时间  30分钟之后
        calendar.add(Calendar.MINUTE, 30);
        orderInfo.setExpireTime(calendar.getTime());
        //进度状态
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
        //总金额
        orderInfo.sumTotalAmount();
        //保存订单
        orderInfoMapper.insert(orderInfo);

        List<String> skuIdList = new ArrayList<>(orderDetailList.size());
        List<Long> skuIdLongList = new ArrayList<>(orderDetailList.size());
        //2：保存订单详情表
        orderDetailList.forEach(orderDetail -> {
            orderDetail.setOrderId(orderInfo.getId());
            orderDetailMapper.insert(orderDetail);
            skuIdList.add(String.valueOf(orderDetail.getSkuId()));
            skuIdLongList.add(orderDetail.getSkuId());
        });
        //3:删除DB   delete from cart_info where user_id = ? and sku_id in ('1','2')
  /*      QueryWrapper wrapper = new QueryWrapper<CartInfo>();
        wrapper.eq("user_id",orderInfo.getUserId());
        wrapper.in("sku_id",skuIdLongList);
        cartInfoMapper.delete(wrapper);*/

        //4:删除购物车中已经提交了商品
  /*      String cacheKey = RedisConst.USER_KEY_PREFIX + orderInfo.getUserId() +
                RedisConst.USER_CART_KEY_SUFFIX;
        redisTemplate.opsForHash().delete(cacheKey,skuIdList.toArray());*/
        //5:发送延迟消息
/*        rabbitService.sendDelayMessage(MqConst.EXCHANGE_DIRECT_ORDER_CANCEL,
            MqConst.ROUTING_ORDER_CANCEL,orderInfo.getId(),MqConst.DELAY_TIME);*/
        return orderInfo.getId();
    }

    //取消订单
    @Override
    public void cancelOrderInfo(Long orderId) {
        //幂等性 ： 防止关闭已经支付了的订单
        //1:查询  校验是否为未支付状态
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if(OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus())){
            //2:更新订单状态为已关闭
            orderInfo.setOrderStatus(OrderStatus.CLOSED.name());
            orderInfo.setProcessStatus(ProcessStatus.CLOSED.name());
            orderInfoMapper.updateById(orderInfo);
        }
    }

    @Override
    public OrderInfo getOrderInfo(Long orderId) {
        return orderInfoMapper.selectById(orderId);
    }

    //更新订单状态
    @Override
    public void updateOrderStatus(Long orderId) {
        //幂等性   ：  大互联网网站 查询是不需要  添加修改删除时  购物车除外
        // 添加修改删除 + 钱相关 ==  必须要做幂等性问题
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if(OrderStatus.UNPAID.name().equals(orderInfo.getOrderStatus())){
            //已支付
            orderInfo.setOrderStatus(OrderStatus.PAID.name());
            orderInfo.setProcessStatus(ProcessStatus.PAID.name());
            orderInfoMapper.updateById(orderInfo);
            //付钱了 赶紧发货吧  订单微服务 是由库存微服务
            rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_WARE_STOCK,
                    MqConst.ROUTING_WARE_STOCK, JSONObject.toJSONString(initWareData(orderId)));

        }
    }

    //拆单
    @Override
    public List<OrderInfo> orderSplit(Long orderId, String wareSkuMap) {
        //originOrderInfo ： 原始订单  父订单
        OrderInfo originOrderInfo = getOrderInfoAndDetails(orderId);
        //                仓库ID        商品ID
        //wareSkuMap   [   {"wareId":"1","skuIds":["2","10"]}  ,{"wareId":"2","skuIds":["3"]}]
        List<Map> wareSkuMapList = JSONObject.parseArray(wareSkuMap, Map.class);

        List<OrderInfo> subOrderInfoList = new ArrayList<>();

        for (Map map : wareSkuMapList) {
            //子订单
            OrderInfo subOrderInfo = new OrderInfo();
            //仓库编号
            subOrderInfo.setWareId(String.valueOf(map.get("wareId")));

            BeanUtils.copyProperties(originOrderInfo,subOrderInfo);
            //订单主表    金额  订单状态  进度状态
            //订单主表  父订单(订单状态为拆单）  多个子订单（支付状态） （记录parent_order_id)
            //订单详情表  订单主表外键（多个子订单的主键)
            //子订单的ID设置成null
            subOrderInfo.setId(null);
            //父ID
            subOrderInfo.setParentOrderId(originOrderInfo.getId());

            List<String> skuIds = JSONObject.parseArray(String.valueOf(map.get("skuIds")), String.class);

            //原来订单详情   [   {"wareId":"1","skuIds":["9"]}  ,{"wareId":"2","skuIds":["15"]}]
            List<OrderDetail> originOrderDetailList = originOrderInfo.getOrderDetailList();
           /* for (OrderDetail orderDetail : originOrderDetailList) {
                orderDetail.getSkuId()

            }*/
           List<Long> orderDetailIds = new ArrayList<>();
            List<OrderDetail> subOrderDetailList = originOrderDetailList.stream().filter(orderDetail -> {
                for (String skuId : skuIds) {
                    if (orderDetail.getSkuId().toString().equals(skuId)) {
                        orderDetailIds.add(orderDetail.getId());
                        return true;
                    }
                }
                return false;
            }).collect(Collectors.toList());
            //金额要重计算
            subOrderInfo.setOrderDetailList(subOrderDetailList);
            subOrderInfo.sumTotalAmount();
            //保存子订单主表
            orderInfoMapper.insert(subOrderInfo);
            //更新新订单详情表的外键（子订单的主键）
            // update order_detail set order_id = ？ where  id in (11,12)
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setOrderId(subOrderInfo.getId());
            orderDetailMapper.update(orderDetail,new QueryWrapper<OrderDetail>()
              .in("id",orderDetailIds));

            subOrderInfoList.add(subOrderInfo);
        }
        //改父订单状态
        originOrderInfo.setOrderStatus(OrderStatus.SPLIT.name());
        originOrderInfo.setProcessStatus(ProcessStatus.SPLIT.name());
        orderInfoMapper.updateById(originOrderInfo);
        //一张订单拆成多张订单 （订单集合）
        return subOrderInfoList;
    }

    //查询订单及订单详情集合
    public OrderInfo getOrderInfoAndDetails(Long orderId){
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if(null != orderInfo){
            List<OrderDetail> orderDetailList = orderDetailMapper.
                    selectList(new QueryWrapper<OrderDetail>()
                    .eq("order_id", orderId));
            orderInfo.setOrderDetailList(orderDetailList);
        }
        return orderInfo;
    }
    //初始化 发送库存微服务所需要的数据
    public Map initWareData(OrderInfo orderInfo){
        Map result = new HashMap();
        //订单表相关
        result.put("orderId",orderInfo.getId());
        result.put("consignee",orderInfo.getConsignee());
        result.put("consigneeTel",orderInfo.getConsigneeTel());
        result.put("orderComment",orderInfo.getOrderComment());
        result.put("orderBody",orderInfo.getTradeBody());
        result.put("deliveryAddress",orderInfo.getDeliveryAddress());
        result.put("paymentWay","ONLINE".equals(orderInfo.getPaymentWay())?2:1);
        result.put("wareId",orderInfo.getWareId());
        //订单详情表相关
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        List<Map> listMap = orderDetailList.stream().map(orderDetail -> {
            Map map = new HashMap();
            map.put("skuId",orderDetail.getSkuId());
            map.put("skuNum",orderDetail.getSkuNum());
            map.put("skuName",orderDetail.getSkuName());
            return map;
        }).collect(Collectors.toList());
        result.put("details",listMap);
        //Java影响性能
        //1:List Map Set 集合类操作 性能影响
        //2:IO SQL   性能影响
        //3:序列化:   反序列化    总结：POJO进转换的时候 就是序列化的时候  转回POJO是反序列化
        return result;

    }
    //初始化 发送库存微服务所需要的数据
    public Map initWareData(Long orderId){

        OrderInfo orderInfo = getOrderInfoAndDetails(orderId);
        Map result = new HashMap();
        //订单表相关
        result.put("orderId",orderInfo.getId());
        result.put("consignee",orderInfo.getConsignee());
        result.put("consigneeTel",orderInfo.getConsigneeTel());
        result.put("orderComment",orderInfo.getOrderComment());
        result.put("orderBody",orderInfo.getTradeBody());
        result.put("deliveryAddress",orderInfo.getDeliveryAddress());
        result.put("paymentWay","ONLINE".equals(orderInfo.getPaymentWay())?2:1);
        //订单详情表相关
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        List<Map> listMap = orderDetailList.stream().map(orderDetail -> {
            Map map = new HashMap();
            map.put("skuId",orderDetail.getSkuId());
            map.put("skuNum",orderDetail.getSkuNum());
            map.put("skuName",orderDetail.getSkuName());
            return map;
        }).collect(Collectors.toList());
        result.put("details",listMap);
        //Java影响性能
        //1:List Map Set 集合类操作 性能影响
        //2:IO SQL   性能影响
        //3:序列化:   反序列化    总结：POJO进转换的时候 就是序列化的时候  转回POJO是反序列化
        return result;
    }



    @Autowired
    private RabbitService rabbitService;
}
